package com.cscp.javastudy.juc.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * CAS中的ABA问题解决办法
 */
public class CasABA2 {

    static AtomicStampedReference<Integer> atomicInteger = new AtomicStampedReference<>(1, 1);

    public static void main(String[] args) {

        new Thread(()->{
            int stamp = atomicInteger.getStamp();//获取版本号
            System.out.println("a1=> "+stamp);//1

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicInteger.compareAndSet(1, 2, atomicInteger.getStamp(), atomicInteger.getStamp() + 1));//true
            System.out.println("a2=> "+atomicInteger.getStamp());//2(因为版本号加1)

            System.out.println(atomicInteger.compareAndSet(2, 1, atomicInteger.getStamp(), atomicInteger.getStamp() + 1));//true
            System.out.println("a3=> "+atomicInteger.getStamp());//3(因为版本号加1)
        },"A").start();

        new Thread(()->{
            int stamp = atomicInteger.getStamp();//获取版本号
            //位置1
            System.out.println("b1=> "+stamp);//1

            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //下面这行执行发现版本号为3，已经不是位置1那行取到的版本号1了，所以修改失败
            System.out.println(atomicInteger.compareAndSet(1, 6, stamp, stamp + 1));//false
            System.out.println("b1=> "+atomicInteger.getStamp());//3
        },"B").start();
    }
}
